package services

import (
	"fmt"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/asserts"
	"github.com/spf13/viper"
	"time"
)

// 端点查找
type EndpointFinder struct {
	v *viper.Viper
}

// 端点配置
type EndpointConfig struct {
	// 链接
	Url string
	// 超时时间
	Timeout *time.Duration
}

// 新建端点查找
func NewEndpointFinder(v *viper.Viper) *EndpointFinder {
	return &EndpointFinder{v: v}
}

// 获取gql端点
func (f *EndpointFinder) GetGqlServerEndpoint(serverName, moduleName string) string {
	return f.getEndpoint(serverName, moduleName, "gql")
}

// 获取rest端点
func (f *EndpointFinder) GetRestServerEndpoint(serverName, moduleName string) string {
	return f.getEndpoint(serverName, moduleName, "restful")
}

// 获取grpc端点
func (f *EndpointFinder) GetGrpcServerEndpoint(serverName, moduleName string) string {
	return f.getEndpoint(serverName, moduleName, "grpc")
}

// 获取gql端点配置
func (f *EndpointFinder) GetGqlServerEndpointConfig(serverName, moduleName string) *EndpointConfig {
	return f.getEndpointConfig(serverName, moduleName, "gql")
}

// 获取gql端点配置
func (f *EndpointFinder) GetRestfulServerEndpointConfig(serverName, moduleName string) *EndpointConfig {
	return f.getEndpointConfig(serverName, moduleName, "restful")
}

// 获取grpc端点配置
func (f *EndpointFinder) GetGrpcServerEndpointConfig(serverName, moduleName string) *EndpointConfig {
	return f.getEndpointConfig(serverName, moduleName, "grpc")
}

// 获取端点配置
func (f *EndpointFinder) getEndpointConfig(serverName, moduleName, protocol string) *EndpointConfig {
	ec := &EndpointConfig{}
	e := f.getEndpoint(serverName, moduleName, protocol)
	t := f.getTimeout(serverName, moduleName, protocol)
	ec.Timeout = t
	ec.Url = e

	return ec
}

// 获取端点
func (f *EndpointFinder) getEndpoint(serverName, moduleName, protocol string) string {
	endpoint := f.v.GetString(fmt.Sprintf("endpoint.%s.%s.%s.url", serverName, moduleName, protocol))
	if endpoint == "" {
		panic(fmt.Sprintf("serviceName:%s,moduleName:%s,protocol:%s，未配置该端点地址", serverName, moduleName, protocol))

	}
	return endpoint
}

// 获取超时时间
func (f *EndpointFinder) getTimeout(serverName, moduleName, protocol string) *time.Duration {
	timeout := f.v.GetString(fmt.Sprintf("endpoint.%s.%s.%s.timeout", serverName, moduleName, protocol))
	if timeout == "" {
		return nil
	}
	d, err := time.ParseDuration(timeout)
	asserts.Nil(err, err)
	return &d
}
